//@flow

/**
 * 调试按钮开关
 */

import React, { Component } from 'react';
import { 
    View,
    PanResponder,
    ViewStyle,
    Text,
    TouchableOpacity,
    Animated,
    StyleSheet,
    GestureResponderEvent,
    PanResponderGestureState,
    TouchableWithoutFeedback,
 } from 'react-native';
import { SCREEN_SIZE } from '../../util/constant/size';
import { Env, EnvType } from '../../config/env';
import { Navigate } from '../../common/navigate';

/**将要用于修改属性的对象模型 */
type DebugBtnPositionType = {
    // opacity? : number,//这里定透明度，不用backgroundColor,因为这个上面的元素也都跟着透明
    left?    : number,
    top?     : number,
}

/**该按钮的大小尺寸 */
const BOX_SIZE : {w:number,h:number} = {w:50,h:50}

/**状态激活之后保留时间长度:默认3秒 */
const ACTIVE_TIME:number = 3;

/**按钮的初始位置 */
const INIT_POSITION : DebugBtnPositionType = {top:SCREEN_SIZE.height*3/4,left:SCREEN_SIZE.width-BOX_SIZE.w}


type State = {
    isActive : boolean,//是否激活属性：该按钮在被拖动后，会在一定时间内保持激活状态,激活状态纯粹就是UI区别，没什么实质区别
    opacity:Animated.Value,//用opacity因为上面的其他样式也都需要透明

    btnXY : Animated.ValueXY,
}
const STYLE_VALUE : {[status:EnvType]:{style:ViewStyle,label:string}} = {
    [EnvType.ENV_DEBUG] : {
        style : {
            backgroundColor: 'orange',
        },
        label:'调试'
    },
    [EnvType.ENV_BETA] : {
        style : {
            backgroundColor: 'green',
        },
        label : '正式'
    },
    [EnvType.ENV_PROD] : {
        style : {
            backgroundColor: 'green',
        },
        label : '正式'
    }
    
}
export class DebugBtn extends Component <{},State> {
    /**初始化state */
    state: State = {
        isActive : false,
        opacity:new Animated.Value(0.3),
        btnXY : new Animated.ValueXY({x:INIT_POSITION.left,y:INIT_POSITION.top})
    }
    
    /**位置信息只能用常量保存，不能用state */
    _previousLeft : number = INIT_POSITION.left;//手势停止的时候，该组件距离左边的距离；
    _previousTop: number = INIT_POSITION.top;//手势停止的时候，该组件距离顶部的位置；
    _viewStyle : {style:DebugBtnPositionType} = {style:{}};//按钮的位置信息
    _debugBtn  : any = null;//需要操作元素实体

    /**成为响应者 */
    _handleStartShouldSetPanResponder=(evt:GestureResponderEvent,gestureState:PanResponderGestureState):boolean => {return true}

    /**是否允许滑动 */
    _handleMoveShouldSetPanResponder=(evt:GestureResponderEvent,gestureState:PanResponderGestureState):boolean => {return true}

    /**手指触碰上去，第一次 
     * 只需要设置成为“激活”状态即可，即显示成低透明度状态
    */
    _handlePanResponderGrant=(evt:GestureResponderEvent,gestureState:PanResponderGestureState):boolean=>{
        this.changeActive(true);
    }

    /**
     * 手指开始滑动，
     * @param {*} isBeActive 
     */
    _handlePanResponderMove=(evt:GestureResponderEvent,gestureState:PanResponderGestureState):boolean=>{
        /**滑动之后的位置 = 上一次记录的位置 + 这次位移的变化量 */
        this._viewStyle.style.left = this._previousLeft + gestureState.dx;
        this._viewStyle.style.top  = this._previousTop + gestureState.dy;
        /**获取到新的位置之后，立即更新UI */
        this.updateStyle()
    }
    /**更新属性的方式更新UI */
    updateStyle(){
        this._debugBtn && this._debugBtn.setNativeProps(this._viewStyle)
    }
    /**是否变成激活状态 
     * 如果是激活：则立即修改UI
     * 如果是失去：则延缓固定时间，再动画的方式修改UI
    */
    changeActive(isBeActive:boolean){
        this.setState({isActive:isBeActive},
            ()=>{
                this.opacityAnimated(isBeActive)
            })
    }
    /**动画效果：透明色 的变换 */
    opacityAnimated(isActive:boolean){
        let opacityValue : number = isActive ? 0.7 : 0.3;
        let duration	 : number = isActive ? 0 : 2000;
        Animated.timing(
            this.state.opacity,
            {
                toValue:opacityValue,
                duration:duration
            }
        ).start()
    }
    /**失去焦点手势 */
    _handlePanResponderEnd=(evt:GestureResponderEvent,gestureState:PanResponderGestureState)=>{
        /**记录结束位置 */
        this._previousLeft += gestureState.dx;
        this._previousTop += gestureState.dy;
        this.setState({
            btnXY:new Animated.ValueXY({x:this._previousLeft,y:this._previousTop})
        },()=>{
            /**动画贴边 */
            this.resetLocation({left:this._previousLeft,top:this._previousTop});
        })
        this.changeActive(false)
    }
    /**自动寻找靠边操作
     * 1，在屏幕中
     * 2，在边缘外
     */
    resetLocation(style:DebugBtnPositionType){
        /**
         * 上下左右边界均不能
         */
        let res : DebugBtnPositionType = {left:style.left,top:style.top};
        if(style.top<0){
            res.top = 0;
        }
        if(style.top>SCREEN_SIZE.height-BOX_SIZE.h){
            res.top = SCREEN_SIZE.height-BOX_SIZE.h
        }
        if(style.left < SCREEN_SIZE.width/2){
            res.left = 0;
        }
        if(style.left > SCREEN_SIZE.width/2){
            res.left = SCREEN_SIZE.width - BOX_SIZE.w
        }
        this._previousLeft = res.left;
        this._previousTop = res.top;
        this.autoCloseSide(res);
    }
    /**动画事件：自动寻找贴壁 */
    autoCloseSide(style:DebugBtnPositionType){
        this._viewStyle.style=style;
        this.updateStyle()
        // Animated.timing(
        //     this.state.btnXY,
        //     {
        //         duration:200,
        //         toValue:new Animated.ValueXY({x:style.left,y:style.top})
        //     }
        // ).start(()=>{
        //     this._viewStyle.style=style;
        //     this.updateStyle()
        // })
    }
    componentDidMount(){    
        this.updateStyle()
    }

    /**生命周期 */
    componentWillMount(){
        this._viewStyle = {
            style:{
                left : this._previousLeft,
                top	 : this._previousTop,
            }
        }
        this.gest = PanResponder.create({
            onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder,
            onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
            onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
            onPanResponderGrant: this._handlePanResponderGrant,
            onPanResponderMove: this._handlePanResponderMove,
            onPanResponderTerminationRequest: (evt, gestureState) => true,
            onPanResponderRelease: this._handlePanResponderEnd,
            onPanResponderTerminate: this._handlePanResponderEnd,
        })
    }

    render(){
        let commonStyle : ViewStyle = this.state.isActive ? styles.active:styles.normal;
        let isRunningDebug : boolean = Env.IS_RUNNING_DEBUG();
        let env : string = Env.GetCurrentEnv();
        let envParams:{style:ViewStyle,label:string} = STYLE_VALUE[env];
        if(isRunningDebug){
            return (
                //最外层，方形圆角
                
                <Animated.View 
                    ref={ref => this._debugBtn = ref}
                    onPress={()=>{
                        console.log("log")
                    }}
                    style={[styles.container,
                            commonStyle,
                            {opacity:this.state.opacity}]} 
                    {...this.gest.panHandlers}>
                    <TouchableOpacity
                        onPress={()=>{
                            // console.log('in')
                            Env.ChangeEnv(env==EnvType.ENV_PROD?EnvType.ENV_DEBUG:EnvType.ENV_PROD)
                            this.forceUpdate()
                        }}
                        onLongPress={()=>{
                            // console.log('long')
                            Navigate.navigate('ReqAnalyzer')
                        }}>
                    {/* 第二层：圆形 */}
                    <View style={[styles.cycle1]}>
                        {/* 第三层：圆形 */}
                        <View style={[styles.cycle2]}>
                            {/* 第四层：圆形 */}
                            <View style={[styles.cycle3,envParams.style]}>
                                {/* <Text>{envParams.label}</Text> */}
                            </View>
                        </View>
                    </View>
                    </TouchableOpacity>
                </Animated.View>
            )
        }else{
            return null;
        }
        
        
    }
}

const styles = StyleSheet.create({
    container : {
        width:50,
        height:50,
        borderRadius: 8,
        backgroundColor: 'rgb(50,50,50)',
        position: 'absolute',
        zIndex:1
    },
    cycle1:{
        width:35,
        height:35,
        borderRadius:17.5,
        backgroundColor: 'rgb(150,150,150)',
        alignItems: 'center',
        justifyContent: 'center',
    },
    cycle2:{
        width:28,
        height:28,
        borderRadius:14,
        backgroundColor: 'rgb(180,180,180)',
        alignItems: 'center',
        justifyContent: 'center',
    },
    cycle3:{
        width:20,
        height:20,
        borderRadius:10,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'rgb(250,250,250)',
    },
    active:{
        opacity : 0.9,
        alignItems: 'center',
        justifyContent: 'center',
    },
    normal:{
        opacity : 0.3,
        alignItems: 'center',
        justifyContent: 'center',
    }
})